package com.sikaryofficial.backend.manager.information;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sikaryofficial.backend.annotation.TenantFilter;
import com.sikaryofficial.backend.config.TenantFilterProperties;
import com.sikaryofficial.backend.domain.dto.req.information.FollowFansListReq;
import com.sikaryofficial.backend.domain.dto.req.information.FollowFriendListReq;
import com.sikaryofficial.backend.domain.dto.req.information.FollowSaveReq;
import com.sikaryofficial.backend.domain.dto.resp.brandspecial.BrandSpecialDTO;
import com.sikaryofficial.backend.domain.dto.resp.information.FollowDTO;
import com.sikaryofficial.backend.domain.entity.Follow;
import com.sikaryofficial.backend.domain.mapping.FollowMapping;
import com.sikaryofficial.backend.service.IFollowService;
import com.sikaryofficial.backend.service.brandspecial.cache.BrandSpecialCacheService;
import com.sikaryofficial.backend.service.follow.cache.FollowCacheService;
import com.sikaryofficial.backend.service.user.UserCacheService;
import com.sikaryofficial.common.core.exception.ServiceException;
import com.sikaryofficial.common.security.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author : qinjinyuan
 * @desc : 文章分类服务
 * @date : 2024/04/10 10:46
 */
@Component
@Slf4j
@SuppressWarnings(value = "unchecked")
public class FollowManager {
    @Autowired
    private IFollowService followService;
    @Autowired
    private UserCacheService userCacheService;
    @Autowired
    private FollowCacheService followCacheService;
    @Autowired
    private TenantFilterProperties tenantFilterProperties;
    @Resource
    private BrandSpecialCacheService brandSpecialCacheService;

    /**
     * 保存或更新
     * <p>
     * 在关注或者粉丝列表中，点击following 或者 follow 成为粉丝
     *
     * @param req
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @TenantFilter
    public Boolean saveOrUpdate(FollowSaveReq req) {
        Long userId = SecurityUtils.getUserId();
        if (Objects.isNull(userId) || userId.equals(req.getFollowingId())) {
            throw new ServiceException("follow error");
        }
        Integer tenantId = tenantFilterProperties.getTenantByBrand(SecurityUtils.getBrand());
        LambdaQueryWrapper<Follow> lambdaQueryWrapper = new LambdaQueryWrapper<Follow>()
                .eq(Follow::getFollowerId, userId)
                .eq(Follow::getFollowingId, req.getFollowingId())
                .eq(Follow::getDeletedVersion, 0L);
        if (Objects.isNull(tenantId)) {
            lambdaQueryWrapper.isNull(Follow::getTenantId);
        } else {
            lambdaQueryWrapper.eq(Follow::getTenantId, tenantId);
        }
        Follow followDB = followService.getOne(lambdaQueryWrapper);
        Long followId = Objects.isNull(followDB) ? IdWorker.getId() : followDB.getFollowId();
        // 新增关注
        Follow follow = FollowMapping.INSTANCE.coverReqToEntity(req);
        follow.setFollowId(followId);
        follow.setFollowerId(userId);
        follow.setFollowingId(req.getFollowingId());
        follow.setFollowerName(SecurityUtils.getUsername());
        follow.setCreatedBy(userId);
        follow.setTenantId(tenantId);
        boolean flag = true;
        if (req.isOptions() && Objects.nonNull(followDB)) {
            follow.setDeletedVersion(follow.getFollowId());
            follow.setUpdatedBy(userId);
            follow.setUpdatedTime(new Date());
            // 取消关注
            flag = followService.update(new LambdaUpdateWrapper<Follow>()
                    .set(Follow::getDeletedVersion, followDB.getFollowId())
                    .set(Follow::getUpdatedBy, userId)
                    .set(Follow::getUpdatedTime, new Date())
                    .set(Follow::getTenantId, tenantId)
                    .eq(Follow::getFollowId, followDB.getFollowId())
                    .eq(Follow::getDeletedVersion, 0L)
            );
        }
        if (!req.isOptions() && Objects.isNull(followDB)) {
            // 新增关注
            flag = followService.save(follow);
        }
        followCacheService.updateFollower(userId, req.getFollowingId(), req.isOptions());
        followCacheService.updateFans(req.getFollowingId(), userId, req.isOptions());
        return flag;
    }

    /**
     * 查询分页列表
     *
     * @param req
     * @return
     */
    @TenantFilter
    public IPage<FollowDTO> friendListPage(FollowFriendListReq req) {
        Long userId = SecurityUtils.getUserId();
        if (Objects.isNull(userId)) {
            return new Page<>(req.getPageNum(), req.getPageSize(), 0);
        }
        Integer tenantId = tenantFilterProperties.getTenantByBrand(SecurityUtils.getBrand());
        String followingName = req.getFollowingName();
        Page<Follow> customerPage = new Page<>(req.getPageNum(), req.getPageSize());
        LambdaQueryWrapper<Follow> queryWrapper = new LambdaQueryWrapper<Follow>()
                .select(Follow::getFollowingId, Follow::getFollowingName)
                .eq(Follow::getDeletedVersion, 0L)
                .eq(Follow::getFollowerId, req.getUserId())
                .eq(Follow::getTenantId, tenantId)
                .likeRight(CharSequenceUtil.isNotBlank(followingName), Follow::getFollowingName, followingName)
                .orderByDesc(Follow::getCreatedTime);
        IPage<Follow> result = followService.page(customerPage, queryWrapper);
        if (CollUtil.isEmpty(result.getRecords())) {
            return new Page<>(req.getPageNum(), req.getPageSize(), 0);
        }
        IPage<FollowDTO> result1 = result.convert(FollowMapping.INSTANCE::coverToDTO);

        List<Long> tenantIdList = tenantFilterProperties.getTenantIdList();
        result1.getRecords().forEach(follow -> {
            Long  followingId = follow.getFollowingId();
            if (CollUtil.isNotEmpty(tenantIdList) && tenantIdList.contains(followingId)) {
                BrandSpecialDTO brandSpecialDTO = brandSpecialCacheService.getBrandSpecialDTO(followingId);
                follow.setBrandSpecialId(brandSpecialDTO.getBrandSpecialId());
                follow.setFollowingAvatar(brandSpecialDTO.getAvatar());
                follow.setNickName(brandSpecialDTO.getBrandNo());
            } else {
                follow.setFollowingAvatar(userCacheService.getSignUserAvatar(followingId));
                follow.setNickName(userCacheService.getSignUserNickName(followingId));
            }
            // 获取用户与 列表中的好友关系
            follow.setHasFollow(req.getUserId().equals(userId) ? Boolean.TRUE : followCacheService.hasFollow(userId, followingId));
        });
        return result1;
    }

    @TenantFilter
    public IPage<FollowDTO> fansListPage(FollowFansListReq req) {
        Long userId = SecurityUtils.getUserId();
        if (Objects.isNull(userId)) {
            return new Page<>(req.getPageNum(), req.getPageSize(), 0);
        }
        Integer tenantId = tenantFilterProperties.getTenantByBrand(SecurityUtils.getBrand());
        String fansName = req.getFollowerName();
        Page<Follow> customerPage = new Page<>(req.getPageNum(), req.getPageSize());
        LambdaQueryWrapper<Follow> queryWrapper = new LambdaQueryWrapper<Follow>()
                .select(Follow::getFollowerId, Follow::getFollowerName)
                .eq(Follow::getDeletedVersion, 0)
                .eq(Follow::getFollowingId, req.getUserId())
                .eq(Follow::getTenantId, tenantId)
                .likeRight(CharSequenceUtil.isNotBlank(fansName), Follow::getFollowerName, fansName)
                .orderByDesc(Follow::getCreatedTime);
        IPage<Follow> result = followService.page(customerPage, queryWrapper);
        if (CollUtil.isEmpty(result.getRecords())) {
            return new Page<>(req.getPageNum(), req.getPageSize(), 0);
        }
        IPage<FollowDTO> result1 = result.convert(FollowMapping.INSTANCE::coverToDTO);
        List<Long> tenantIdList = tenantFilterProperties.getTenantIdList();
        result1.getRecords().forEach(follow -> {
            Long followerId = follow.getFollowerId();
            if (CollUtil.isNotEmpty(tenantIdList) && tenantIdList.contains(followerId)) {
                BrandSpecialDTO brandSpecialDTO = brandSpecialCacheService.getBrandSpecialDTO(followerId);
                follow.setBrandSpecialId(brandSpecialDTO.getBrandSpecialId());
                follow.setFollowingAvatar(brandSpecialDTO.getAvatar());
                follow.setNickName(brandSpecialDTO.getBrandNo());
            } else {
                follow.setFollowingAvatar(userCacheService.getSignUserAvatar(followerId));
                follow.setNickName(userCacheService.getSignUserNickName(followerId));
            }
            // 获取用户与 列表中的好友关系
            follow.setHasFollow(followCacheService.hasFollow(userId, followerId));
        });
        return result1;
    }
}